#pragma once

#include <OIS.h>
#include <Ogre.h>
#include <map>
#include <string>
#include <vector>

using namespace std;

typedef enum {
	ACTION_NONE = 0,
	ACTION_SHUTDOWN,
	ACTION_PITCH_UP,
	ACTION_PITCH_DOWN,
	ACTION_ROLL_LEFT,
	ACTION_ROLL_RIGHT,
	ACTION_TURN_LEFT,
	ACTION_TURN_RIGHT,
	ACTION_GO_UP,
	ACTION_GO_DOWN,
	ACTION_GO_LEFT,
	ACTION_GO_RIGHT,
	ACTION_GO_FORWARD,
	ACTION_GO_BACKWARD,
	ACTION_MODE_MANUAL,
	ACTION_MODE_AUTOMATIC,
	ACTION_MODE_POWER_STEERING,
	ACTION_MODE_PARKING,
	ACTION_MODE_ARCADE,
	FAST_ACTION_MODE_MANUAL,
	FAST_ACTION_MODE_AUTOMATIC,
	FAST_ACTION_MODE_POWER_STEERING,
	FAST_ACTION_MODE_PARKING,
	FAST_ACTION_MODE_ARCADE
} Action;

class ActionMap {
public:
	ActionMap(string settingsFile = "");
	~ActionMap();
	void loadActionMap(string settingsFile);
	void saveActionMap(string settingsFile);
	Action getAction(const OIS::KeyEvent &evt, bool modeParking = false);
	void mapAction(OIS::KeyCode key, Action action);
protected:
	map<OIS::KeyCode, Action> mMap, mMapParking;
};

class InputHandler :
	public OIS::MouseListener,
	public OIS::KeyListener,
	public OIS::JoyStickListener
{
private:
	//OIS Input devices
	OIS::InputManager *m_ois;
	OIS::Mouse *mMouse;
	OIS::Keyboard *mKeyboard;
	OIS::JoyStick *mJoy;

	Ogre::RenderWindow* mWindow;
	
	vector<Action> currentEvents;
	ActionMap actionMap;
	bool modeAutomatic, modePowerSteering, modeParking, modeArcade;
	static InputHandler* singleton;
public:
	InputHandler(Ogre::RenderWindow *window);
	~InputHandler();

	void setWindowExtents(int width, int height);
	void capture();
	static InputHandler* getSingleton();
	void updateScreener();
	
	const vector<Action> getCurrentEvents();
	bool setMode(const Action& action, bool keyReleased = false);
	bool getModeAutomatic();
	bool getModeArcade();
	bool getModePowerSteering();
	bool getModeParking();
	

	// MouseListener
	bool mouseMoved(const OIS::MouseEvent &evt);
	bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID);
	bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID);
	
	// KeyListener
	bool keyPressed(const OIS::KeyEvent &evt);
	bool keyReleased(const OIS::KeyEvent &evt);
	
	// JoyStickListener
	bool buttonPressed(const OIS::JoyStickEvent &evt, int index);
	bool buttonReleased(const OIS::JoyStickEvent &evt, int index);
	bool axisMoved(const OIS::JoyStickEvent &evt, int index);
	bool povMoved(const OIS::JoyStickEvent &evt, int index);
};
